﻿function Add-Release {
<#
.DESCRIPTION
	Add a new release to a codeplex project. This function uses the CodePlex webservices API to add a new release.
	
	You need to use Upload-Release function add files to a release.
.SYNOPSIS
	Adds a new release to a CodePlex project
.PARAMETER projectName
	Project Name of a codeplex project.
.PARAMETER releaseName
	Release Name of a codeplex release under the specified project.
.PARAMETER releaseDescription
	Release description of a codeplex release under the specified project. If not specified, release name will be used as release description
.PARAMETER releaseStatus
	Release status of a codeplex release. The value of this parameter can be "planning" or "alpha" or "beta" or "stable"
.PARAMETER public
	If specified, the release will be made visible to public
.PARAMETER default
	If specified, the release will be made the default release in the CodePlex project
.PARAMETER userName
	UserName to authenticate to the codeplex prject and create a new release. Remember, this user should have developer rights, at least.
.PARAMETER password
	Password to authenticate to the codeplex prject and create a new release.
.OUTPUTS
	A release ID of the newly created release will be shown
.EXAMPLE
	Add-Release -projectName "PSCodePlex" -releaseName "PSCodePlex 0.2" -releaseStatus "Beta" -userName "xxxx" -password "****"
	
	Description
	-----------
	The above example creates a new private release under PSCodePlex project which is not the default release.
.EXAMPLE
	Add-Release -projectName "PSCodePlex" -releaseName "PSCodePlex 0.2" -releaseStatus "Beta" -userName "xxxx" -password "****" -public
	
	Description
	-----------
	The above example creates a new public release under PSCodePlex project which is not the default release.
.EXAMPLE
	Add-Release -projectName "PSCodePlex" -releaseName "PSCodePlex 0.2" -releaseStatus "Beta" -userName "xxxx" -password "****" -public -default
	
	Description
	-----------
	The above example creates a new public release under PSCodePlex project which is the default release.
.EXAMPLE
	$descriptionText = [String](Get-Content C:\Scripts\CodePlex\ReleaseNotes.txt)
	
	Add-Release -projectName "PSCodePlex" -releaseName "PSCodePlex 0.2" -releaseDescription $descriptiontext -releaseStatus "Beta" -userName "xxxx" -password "****"
	
	Description
	-----------
	The above example creates a new private release under PSCodePlex project with the contents of C:\scripts\CodePlex\releasenotes.txt as the release description
.LINK
	Online version: http://www.ravichaganti.com/blog
.LINK
	http://pscodeplex.codeplex.com
#>
	[CmdletBinding()]
	param (
		[Parameter(Mandatory=$True)]
   		[String]$projectName,
  		
   		[Parameter(Mandatory=$True)]
		[String]$releaseName,
		
		[Parameter(Mandatory=$false)]
		[String]$releaseDescription,
		
		[Parameter(Mandatory=$True)]
		[ValidateSet("Planning", "Alpha", "Beta", "Stable")]
   		[String]$releaseStatus,
		
		[Parameter(Mandatory=$false)]
   		[Switch]$Public,
		
		[Parameter(Mandatory=$false)]
   		[Switch]$Default,
		
		[Parameter(Mandatory=$True)]
   		[String]$userName,
		
		[Parameter(Mandatory=$True)]
   		[String]$password
	)
	
	try {
		Write-Verbose "Connecting to CodePlex webservice"
		$cpService = New-WebServiceProxy -Uri "https://www.codeplex.com/Services/ReleaseService.asmx" -Namespace CodePlex
		Write-Verbose "Connection established"
	}
	catch {
		Write-Warning "There was an error accessing the codeplex webservice"
		Write-Warning $_
		return $false
	}
	
	#Make current date as the release date
	$releaseDate = Get-Date
	
	if (!$releaseDescription) {
		$releaseDescription = $releaseName
		Write-Verbose "Using $releaseName as release description"
	}
	
	try {
		Write-Verbose "attempting to create the release"
		$releaseID = $cpService.CreateARelease($projectName,$releaseName,$releaseDescription,$releaseDate,$releasestatus,$Public,$Default,$userName,$password)
		Write-Host -ForegroundColor Green "`n$releaseName release created with release ID: $releaseID"
	}
	
	catch {
		Write-Warning "Error occured while creaitng a new release"
		Write-Warning $_
		return $false
	}
}

Function Upload-Release {
<#
.DESCRIPTION
	Uploads files to a release on CodePlex. This function uses the CodePlex webservices API to upload files to a release.
	As of release 0.2, you need to put all release files in a folder and provide that as value to releaseFolderPath parameter.
	
.SYNOPSIS
	Uploads files to a release on CodePlex
.PARAMETER projectName
	Project Name of a codeplex project.
.PARAMETER releaseName
	Release Name of a codeplex release under the specified project.
.PARAMETER releaseFolderPath
	Folder path containing all release files.
.PARAMETER releaseType
	Specifies the type of release. Value to this parameter can be "RunTimeBinary" or "Source Code" or "Documentation" or "Example"
.PARAMETER userName
	UserName to authenticate to the codeplex prject and create a new release. Remember, this user should have developer rights, at least.
.PARAMETER password
	Password to authenticate to the codeplex prject and create a new release.
.OUTPUTS
	Specifies if the release upload was successful or not.
.EXAMPLE
	Upload-Release -projectName "PSCodePlex" -releaseName "PS CodePlex 0.2" -releaseFolderPath c:\Scripts\CodePlex -releaseType "SourceCode" -userName "xxxx" -password "****"
	
	Description
	-----------
	The above example uploads release files to a new release on CodePlex.
.LINK
	Online version: http://www.ravichaganti.com/blog
.LINK
	http://pscodeplex.codeplex.com
#>
	[CmdletBinding()]
	param (
		[Parameter(Mandatory=$True)]
   		[String]$projectName,
  
   		[Parameter(Mandatory=$True)]
		[String]$releaseName,
		
		[Parameter(Mandatory=$True)]
   		[String]$releaseFolderPath,
		
		[Parameter(Mandatory=$True)]
		#Specifies if the new release is "RunTimeBinary" or "SoruceCode" or "Documentation" or an "example".
		[ValidateSet("RuntimeBinary", "SourceCode", "Documentation", "Example")]
   		[String]$releaseType,
		
		[Parameter(Mandatory=$True)]
		#UserName to authenticate to the codeplex prject and create a new release. Remember, this user should have developer rights, at least.
   		[String]$userName,
		
		[Parameter(Mandatory=$True)]
		#Password to authenticate to the codeplex project.
   		[String]$password
	)
	
	try {
		Write-Verbose "`nConnecting to CodePlex webservice"
		$cpService = New-WebServiceProxy -Uri "https://www.codeplex.com/Services/ReleaseService.asmx" -Namespace CodePlex
		Write-Verbose "Connection established"
	}
	catch {
		Write-Warning "There was an error accessing the codeplex webservice"
		Write-Warning $_
		return $false
	}
	
	#create an array for all files in the release and initiate the releaseFile instance
	$releaseFiles = @()
	
	#set recommendedFileName to rName
	Write-Verbose "$releaseName will be used as the release file name"
	$releaseFileName = $releaseName
	
	try {
		Write-Verbose "Adding files to a release file"
		if ((Get-Item $releaseFolderPath | % { $_.PSIsContainer })) {
			Get-ChildItem $releaseFolderPath | % {
					Write-Verbose "Adding file: $_"
					$releaseFile = New-Object CodePlex.ReleaseFile
					$releaseFile.FileName = $_.Name
					$releaseFile.FileData = [System.IO.File]::ReadAllBytes($_.FullName)
					$releaseFile.FileType = $releaseType
					$releaseFiles += $releaseFile
				}
			} else {
				Write-Warning "`n$releaseFolderPath is not a folder.Exiting..."
			}
		}
			
	catch {
		Write-Warning "`nError occured while adding files"
		Write-Warning $_
		return $false
	}
	
	try {
		Write-Verbose "Attempting to upload the release files"
		$cpService.UploadTheReleaseFiles($projectName,$releaseName,$releaseFiles,$releaseFileName,$userName,$password)
		Write-Host -ForegroundColor Green "`nRelease upload complete"
	}
	catch {
		Write-Warning "Error occurred while uploading file to codeplex"
		Write-Warning $_
	}
}